﻿using System;
using System.IO;
using System.Net;
using System.Linq;
using System.Text;
using System.Activities;
using System.Activities.Expressions;
using System.Activities.Presentation.PropertyEditing;
using System.Activities.Statements;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Markup;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlTypes;

namespace Vision.Core.ActivityComponents.Sql
{
    /// <summary>
    /// 
    /// </summary>    
    [Designer(typeof(SqlExecuteNonQueryDesigner))]
    public class SqlExecuteNonQuery : NativeActivity
    {
        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]
        [RequiredArgument]
        [DefaultValue(null)]
        public InArgument<System.Data.SqlClient.SqlConnection> SqlConn { get; set; }

        [Category("Input")]
        [RequiredArgument]
        [DefaultValue("")]
        public InArgument<string> SqlCmdText { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]
        [DefaultValue(null)]
        public InArgument<Dictionary<string, object>> SqlParameters { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]
        [DefaultValue(null)]
        public CmdType SqlCmdType { get; set; }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="metadata"></param>
        protected override void CacheMetadata(NativeActivityMetadata metadata)
        {
            RuntimeArgument sqlConnectionArgument = new RuntimeArgument("SqlConn", typeof(System.Data.SqlClient.SqlConnection), ArgumentDirection.In, true);
            metadata.Bind(this.SqlConn, sqlConnectionArgument);
            metadata.AddArgument(sqlConnectionArgument);

            RuntimeArgument sqlCmdTextArgument = new RuntimeArgument("SqlCmdText", typeof(string), ArgumentDirection.In, true);
            metadata.Bind(this.SqlCmdText, sqlCmdTextArgument);
            metadata.AddArgument(sqlCmdTextArgument);

            RuntimeArgument sqlParametersArgument = new RuntimeArgument("SqlParameters", typeof(Dictionary<string, object>), ArgumentDirection.In, false);
            metadata.Bind(this.SqlParameters, sqlParametersArgument);
            metadata.AddArgument(sqlParametersArgument);            
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        protected override void Execute(NativeActivityContext context)
        {
            var paramList = this.SqlParameters.Get(context);

            using (SqlCommand sqlCmd = new SqlCommand()){
                sqlCmd.Connection = this.SqlConn.Get(context);
                sqlCmd.CommandText = this.SqlCmdText.Get(context);
                sqlCmd.CommandType = this.GetSqlCommandTypeFromCmdType(this.SqlCmdType);                
                if (paramList != null){
                    foreach (string param in paramList.Keys){
                        sqlCmd.Parameters.Add(new SqlParameter(param, paramList[param]));
                    }
                }
                sqlCmd.ExecuteNonQuery();                
            }    
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cmdType"></param>
        /// <returns></returns>
        private System.Data.CommandType GetSqlCommandTypeFromCmdType(CmdType cmdType)
        {
            switch (cmdType){
                case CmdType.StoredProcedure:
                    return System.Data.CommandType.StoredProcedure;
                case CmdType.Text:
                    return System.Data.CommandType.Text;
                default:
                    return System.Data.CommandType.Text;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public enum CmdType
        {
            StoredProcedure,
            Text
        }
    }
}
